import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;

class AIService {
  static final AIService _instance = AIService._internal();
  factory AIService() => _instance;
  AIService._internal();

  final Dio _dio = Dio();
  final uuid = Uuid();

  // Pl@ntNet API凭证
  final String plantnetApiKey = '2b10slFAsNzNMBLgsQOcVpFK';
  final String plantnetApiUrl = 'https://my-api.plantnet.org/v2/identify/all';

  // AI聊天API设置
  final String aiApiUrl = 'https://api.wiseaii.com/wiseai/v1/chat';
  final String bundleId = 'com.olii.ios';
  String? conversationId;
  late String sessionId;

  // 初始化服务
  void init() {
    debugPrint('初始化AI服务...');
    // 为AI聊天生成唯一会话ID
    sessionId =
        '${DateTime.now().millisecondsSinceEpoch}_${uuid.v4().substring(0, 16)}';
    debugPrint('创建AI聊天会话ID: $sessionId');
  }

  // 使用Pl@ntNet API识别植物
  Future<Map<String, dynamic>> recognize_plant(File imageFile) async {
    if (imageFile.path.isEmpty) {
      debugPrint('错误：未提供图片文件');
      throw Exception("No image file provided");
    }

    debugPrint('开始识别植物...');

    try {
      debugPrint('图片路径: ${imageFile.path}');
      debugPrint('图片大小: ${await imageFile.length()} bytes');

      // 创建多部分请求
      final uri = Uri.parse('$plantnetApiUrl?api-key=$plantnetApiKey');
      final request = http.MultipartRequest('POST', uri);

      // 添加器官字段
      request.fields['organs'] = 'auto';

      // 添加图片文件
      request.files.add(
        await http.MultipartFile.fromPath(
          'images',
          imageFile.path,
          filename: path.basename(imageFile.path),
        ),
      );

      debugPrint('发送HTTP请求到: $uri');
      debugPrint('请求参数: ${request.fields}');
      debugPrint(
        '请求文件: ${request.files.map((f) => f.field + ': ' + f.filename!).join(', ')}',
      );

      // 发送请求
      final streamedResponse = await request.send();
      final response = await http.Response.fromStream(streamedResponse);

      debugPrint('API响应状态码: ${response}');

      if (response.statusCode == 200) {
        debugPrint('API请求成功');
        final data = json.decode(response.body);

        if (data['results'] != null && data['results'].isNotEmpty) {
          // 获取最可能的植物识别结果
          final topResult = data['results'][0];
          final plantName = topResult['species']['scientificNameWithoutAuthor'];
          final score = topResult['score'];

          debugPrint('成功识别植物: $plantName，置信度: ${(score * 100).toStringAsFixed(2)}%');

          // 使用AI获取植物养护信息
          final careInfo = await get_plant_care_information(plantName);

          return {
            'success': true,
            'plantName': plantName,
            'score': score,
            'careInfo': careInfo['formattedText'],
            'careDetails': careInfo['details'],
          };
        } else {
          debugPrint('API返回无结果，可能未能识别该植物');
          return {
            'success': false,
            'error': 'No plant identified in the image',
          };
        }
      } else {
        debugPrint('API请求失败，状态码: ${response.statusCode}');
        return {
          'success': false,
          'error': 'Plant identification failed: ${response.statusCode}',
          'details': response.body,
        };
      }
    } catch (e) {
      debugPrint('识别植物时发生错误: $e');
      return {
        'success': false,
        'error': 'Error during plant identification: $e',
      };
    }
  }

  // 使用AI聊天获取植物养护信息，并提取结构化数据
  Future<Map<String, dynamic>> get_plant_care_information(String plantName) async {
    debugPrint('正在获取植物养护信息: $plantName');

    try {
      final response = await _dio.post(
        aiApiUrl,
        data: {
          'bundle_id': bundleId,
          'content':
              'Please provide care information for the plant "$plantName" with the following structured format:\n\n'
              '## Care Information\n'
              'First give a brief overview of the plant, then list specific care details using bullet points (•) for:\n'
              '• Light requirements\n'
              '• Soil preferences\n'
              '• Watering needs\n'
              '• Fertilizing recommendations\n'
              '• Temperature tolerance\n\n'
              '## Flowering Time\n'
              'Describe when and how the plant flowers.\n\n'
              '## Common Problems\n'
              'List common issues using bullet points (•):\n'
              '• Problem 1 with brief solution\n'
              '• Problem 2 with brief solution\n'
              '• Etc.\n\n'
              'Make sure to use "•" for bullet points, not "-" or "*". Respond in English only.',
          'content_type': 'text',
          'session_id': sessionId,
          if (conversationId != null) 'conversation_id': conversationId,
        },
        options: Options(headers: {'Content-Type': 'application/json'}),
      );

      if (response.statusCode == 200) {
        final data = response.data;
        debugPrint('AI API响应: $data');

        if (data['code'] == 1003 && data['data']['answer'] != null) {
          // 保存会话ID以供将来请求使用
          conversationId = data['data']['conversation_id'];
          final String originalText = data['data']['answer'];
          debugPrint('获取到植物养护信息，会话ID: $conversationId');

          // 提取结构化数据
          Map<String, String> details = _extract_plant_care_details(originalText);

          return {
            'formattedText': originalText, // 保留原始文本
            'details': details, // 添加结构化数据
          };
        } else {
          debugPrint('AI API返回错误或空响应: ${data['message']}');
          return {
            'formattedText':
                "Unable to retrieve care information for this plant.",
            'details': {},
          };
        }
      } else {
        debugPrint('AI API请求失败，状态码: ${response.statusCode}');
        return {
          'formattedText':
              "Failed to get care information. Please try again later.",
          'details': {},
        };
      }
    } catch (e) {
      debugPrint('获取植物养护信息时发生错误: $e');
      return {
        'formattedText': "Error retrieving care information: $e",
        'details': {},
      };
    }
  }

  // 从AI回答中提取结构化的植物养护信息
  Map<String, String> _extract_plant_care_details(String text) {
    Map<String, String> details = {
      'careInfo': '',
      'floweringTime': '',
      'commonProblems': '',
    };

    // 移除Markdown标题中多余的#号，简化处理
    String cleanedText = text.replaceAll('###', '##');

    // 尝试提取养护信息（更精确的正则表达式）
    final careRegex = RegExp(
      r'(?:Care Information|Care Info)[:\s]+([\s\S]*?)(?=(?:##\s*Flowering Time|##\s*Flowering|##\s*Common Problems|$))',
      caseSensitive: false,
    );
    final careMatch = careRegex.firstMatch(cleanedText);
    if (careMatch != null && careMatch.group(1) != null) {
      details['careInfo'] = careMatch.group(1)!.trim();
    }

    // 尝试提取开花时间（更精确的正则表达式）
    final flowerRegex = RegExp(
      r'(?:##\s*Flowering Time|##\s*Flowering)[:\s]+([\s\S]*?)(?=(?:##\s*Common Problems|$))',
      caseSensitive: false,
    );
    final flowerMatch = flowerRegex.firstMatch(cleanedText);
    if (flowerMatch != null && flowerMatch.group(1) != null) {
      details['floweringTime'] = flowerMatch.group(1)!.trim();
    }

    // 尝试提取常见问题（更精确的正则表达式）
    final problemsRegex = RegExp(
      r'##\s*Common Problems[:\s]+([\s\S]*?)(?=$)',
      caseSensitive: false,
    );
    final problemsMatch = problemsRegex.firstMatch(cleanedText);
    if (problemsMatch != null && problemsMatch.group(1) != null) {
      details['commonProblems'] = problemsMatch.group(1)!.trim();
    }

    // 如果没有匹配到结构化信息，尝试智能分割文本
    if (details['careInfo']!.isEmpty &&
        details['floweringTime']!.isEmpty &&
        details['commonProblems']!.isEmpty) {
      debugPrint('未能使用正则表达式提取结构化信息，尝试智能分割');

      // 按照段落分割
      List<String> paragraphs = cleanedText.split('\n\n');

      // 假设第一部分是养护信息
      if (paragraphs.isNotEmpty) {
        details['careInfo'] = paragraphs[0].trim();
      }

      // 查找包含开花相关词汇的段落
      for (String paragraph in paragraphs) {
        String lowerParagraph = paragraph.toLowerCase();
        if (lowerParagraph.contains('flower') ||
            lowerParagraph.contains('bloom')) {
          details['floweringTime'] = paragraph.trim();
          break;
        }
      }

      // 查找包含问题相关词汇的段落
      for (String paragraph in paragraphs) {
        String lowerParagraph = paragraph.toLowerCase();
        if (lowerParagraph.contains('problem') ||
            lowerParagraph.contains('issue') ||
            lowerParagraph.contains('disease') ||
            lowerParagraph.contains('pest')) {
          details['commonProblems'] = paragraph.trim();
          break;
        }
      }
    } else {
      debugPrint('成功使用正则表达式提取结构化信息');
    }

    // 格式化已提取的内容为Markdown
    if (details['careInfo']!.isNotEmpty) {
      details['careInfo'] = _formatForMarkdown(details['careInfo']!);
    }
    if (details['floweringTime']!.isNotEmpty) {
      details['floweringTime'] = _formatForMarkdown(details['floweringTime']!);
    }
    if (details['commonProblems']!.isNotEmpty) {
      details['commonProblems'] = _formatForMarkdown(
        details['commonProblems']!,
      );
    }

    return details;
  }

  // 格式化文本为Markdown格式
  String _formatForMarkdown(String text) {
    // 处理星号标记为Markdown格式
    String formatted = text;

    // 转换 "**关键词**:" 格式为Markdown格式的标题
    formatted = formatted.replaceAllMapped(
      RegExp(r'\*\*([^*]+)\*\*:'),
      (Match match) => '\n### ${match.group(1)}\n',
    );

    // 转换 "- **关键词**:" 格式为Markdown格式的加粗
    formatted = formatted.replaceAllMapped(
      RegExp(r'- \*\*([^*]+)\*\*:'),
      (Match match) => '- **${match.group(1)}**:',
    );

    // 处理单独的破折号（无内容）的问题
    formatted = formatted.replaceAll('- \n', '');
    formatted = formatted.replaceAll('-\n', '');
    formatted = formatted.replaceAll('- ', '• ');

    // 确保每个列表项都有正确的格式
    formatted = formatted.replaceAll(RegExp(r'(?<!\n)• '), '\n• ');

    // 替换双星号但没有冒号的情况 (保留为加粗)
    formatted = formatted.replaceAllMapped(
      RegExp(r'\*\*([^*:]+)\*\*'),
      (Match match) => '**${match.group(1)}**',
    );

    // 确保每个标题后有空行
    formatted = formatted.replaceAll(
      RegExp(r'(### [^\n]+)(\n[^#•])'),
      r'$1\n\n$2',
    );

    // 处理空白项目符号
    formatted = formatted.replaceAll('•  ', '• ');

    // 处理连续的换行符
    formatted = formatted.replaceAll('\n\n\n', '\n\n');

    return formatted;
  }

  // 向AI提问后续问题
  Future<String> ask_follow_up_question(String question) async {
    if (conversationId == null) {
      debugPrint('错误：没有有效的会话');
      return "No active conversation. Please identify a plant first.";
    }

    debugPrint('发送后续问题: $question');

    try {
      final response = await _dio.post(
        aiApiUrl,
        data: {
          'bundle_id': bundleId,
          'content': question,
          'content_type': 'text',
          'session_id': sessionId,
          'conversation_id': conversationId,
        },
        options: Options(headers: {'Content-Type': 'application/json'}),
      );

      if (response.statusCode == 200) {
        final data = response.data;

        if (data['code'] == 1003 && data['data']['answer'] != null) {
          debugPrint('收到AI回答');
          return data['data']['answer'];
        } else {
          debugPrint('AI API返回错误或空响应');
          return "No response received. Please try again.";
        }
      } else {
        debugPrint('AI API请求失败，状态码: ${response.statusCode}');
        return "Failed to get a response. Please try again later.";
      }
    } catch (e) {
      debugPrint('提问时发生错误: $e');
      return "Error sending your question: $e";
    }
  }
}
